<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
    <title>Binding Test Single</title>
    <link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.10.0.css">
</head>
<body>
    <div id="qunit"></div>
    <div id="qunit-fixture"></div>
    <script src="https://code.jquery.com/qunit/qunit-2.10.0.js"></script>

    <script type="text/javascript">
    QUnit.module('BindingTestSingle', (hooks) =>
    {
        hooks.before(async () =>
        {
            await CefSharp.BindObjectAsync("boundAsync");
        });

        QUnit.test("Pass callback(promise) that is conditionally invoked:", async (assert) =>
        {
            let convertPromiseToCefSharpCallback = function (p)
            {
                let f = function (callbackId, ...args)
                {
                    //We immediately return CefSharpDefEvalScriptRes as we will be
                    //using a promise and will call sendEvalScriptResponse when our
                    //promise has completed
                    (async function ()
                    {
                        try
                        {
                            //Await the promise
                            let response = await p(...args);

                            //We're done, let's send our response back to our .Net App
                            cefSharp.sendEvalScriptResponse(callbackId, true, response, true);
                        }
                        catch (err)
                        {
                            //An error occurred let's send the response back to our .Net App
                            cefSharp.sendEvalScriptResponse(callbackId, false, err.message, true);
                        }
                    })();

                    //Let CefSharp know we're going to be defering our response as we have some async/await
                    //processing to happen before our callback returns it's value
                    return "CefSharpDefEvalScriptRes";
                }

                return f;
            }

            //The function convertPromiseToCefSharpCallback can be used in your own projects
            //Pass in a function that wraps your promise, not your promise directly
            let callback = convertPromiseToCefSharpCallback(function (msg)
            {
                return new Promise((resolve, reject) =>
                {
                    setTimeout(() =>
                    {
                        resolve(msg);
                    }, 300);
                });
            });

            const expectedResult = "Callback has not been invoked";
            const actualResult = await boundAsync.javascriptOptionalCallbackEvalPromise(false, expectedResult, callback);
            assert.equal(expectedResult, actualResult, "Echo response after promise execution");

            const expectedSecondResult = "Callback has been invoked";
            const actualSecondResult = await boundAsync.javascriptOptionalCallbackEvalPromise(true, expectedSecondResult, callback);
            assert.equal(expectedSecondResult, actualSecondResult, "Echo response after promise execution");
        });
    });
    </script>

</body>
</html>
